package co.baiku.boot.config;

import co.baiku.boot.swagger.properties.SwaggerConstants;
import co.baiku.boot.swagger.properties.SwaggerProperties;
import com.google.common.base.Predicates;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import;
import org.springframework.core.env.Environment;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.ParameterBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.schema.ModelRef;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.service.Parameter;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;
import springfox.documentation.swagger2.configuration.Swagger2DocumentationConfiguration;

import java.util.ArrayList;
import java.util.List;

@Configuration
@ConditionalOnProperty(name = SwaggerConstants.CONFIG_SWAGGER_ENABLED, matchIfMissing = true)
@Import({
        Swagger2DocumentationConfiguration.class
})
@EnableConfigurationProperties(SwaggerProperties.class)
@EnableSwagger2
public class SwaggerConfig {

    @Autowired
    private Environment env;

    @Autowired
    private SwaggerProperties swaggerProperties;

    /**
     * 隐藏swagger文档
     *
     * @return
     */
    private boolean hideSwaggerDocs() {
        // 生产环境不启用swagger文档，为了安全
        return "prd".equalsIgnoreCase(env.getActiveProfiles()[0]);
    }

    public SwaggerApiInfo apiInfo() {
        SwaggerApiInfo apiInfo = new SwaggerApiInfo();
        apiInfo.setHideSwaggerDocs(hideSwaggerDocs());
        apiInfo.setApiInfo(new ApiInfoBuilder()
                .title(swaggerProperties.getTitle())
                .description(swaggerProperties.getDescription())
                .termsOfServiceUrl(swaggerProperties.getTermsOfServiceUrl())
                .version(swaggerProperties.getVersion()).build());

        return apiInfo;
    }


    @Bean
    public Docket createWebApi() {
        SwaggerApiInfo apiInfo = apiInfo();
        List<Parameter> parameters = new ArrayList<>();
        parameters.add(new ParameterBuilder().name("Authorization").description("认证 Token").parameterType("header")
                .required(false).modelRef(new ModelRef("string")).build());
        return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo.getApiInfo()).select()
                .apis(RequestHandlerSelectors.any())
                .paths(Predicates.not(PathSelectors.regex("/error.*")))
                .paths(apiInfo.hideSwaggerDocs ? PathSelectors.none() : PathSelectors.any()).build().globalOperationParameters(parameters);
    }

    public static class SwaggerApiInfo {
        private boolean hideSwaggerDocs = true;
        private ApiInfo apiInfo;

        public boolean isHideSwaggerDocs() {
            return hideSwaggerDocs;
        }

        public void setHideSwaggerDocs(boolean hideSwaggerDocs) {
            this.hideSwaggerDocs = hideSwaggerDocs;
        }

        public ApiInfo getApiInfo() {
            return apiInfo;
        }

        public void setApiInfo(ApiInfo apiInfo) {
            this.apiInfo = apiInfo;
        }
    }
}
